1 module hip.image_backend.webassembly;
2 
3 
4 version(WebAssembly)
5 {
6     import hip.wasm;
7     import hip.api.data.image;
8     extern(C) struct BrowserImage
9     {
10         size_t handle;
11         bool valid() const {return handle > 0;}
12         alias handle this;
13     }
14     //Returns a BrowserImage, but can't use it in type directly.
15     extern(C) size_t WasmDecodeImage(
16         size_t imgPathLength, char* imgPathChars, ubyte* data, size_t dataSize,
17         JSDelegateType!(void delegate(BrowserImage)) onImageLoad
18     );
19 
20     extern(C) size_t WasmImageGetWidth(size_t);
21     extern(C) size_t WasmImageGetHeight(size_t);
22     extern(C) ubyte* WasmImageGetPixels(size_t);
23     extern(C) void WasmImageDispose(size_t);
24 
25     final class HipWasmImageDecoder : IHipAnyImageDecoder
26     {
27         //Everything here needs to be cached for not calling the Wasm bridge.
28         private uint width, height;
29         private size_t timePixelsGet = 0;
30         BrowserImage img;
31         string path;
32         ubyte[] pixels;
33         this(string path)
34         {
35             assert(path, "HipWasmImageDecoder requires a path.");
36             this.path = path;
37         }
38         bool startDecoding(void[] data, void delegate() onSuccess, void delegate() onFailure)
39         {
40             import hip.console.log;
41             img = WasmDecodeImage(path.length, cast(char*)path.ptr, cast(ubyte*)data.ptr, data.length, sendJSDelegate!((BrowserImage _img)
42             {
43                 assert(img == _img, "Different image returned!");
44                 if(img.valid)
45                 {
46                     width = WasmImageGetWidth(img);
47                     height = WasmImageGetHeight(img);
48                     pixels = getWasmBinary(WasmImageGetPixels(img));
49                     hiplog(width, " x ", height, " ", pixels.length, " bytes");
50 
51                     (width != 0 && height != 0) ? onSuccess() : onFailure();
52                 }
53                 else
54                 {
55                     loglnError("Corrupted JS image object.");
56                     onFailure();
57                 }
58             }).tupleof);
59 
60             return img.valid && width != 0 && height != 0;
61         }
62         uint getWidth() const {return width;}
63         uint getHeight() const {return height;}
64         const(ubyte)[] getPixels() const 
65         {
66             return cast(const(ubyte)[])pixels;
67         }
68         ubyte getBytesPerPixel() const {return 4;}
69         const(ubyte)[] getPalette() const {return null;}
70         void dispose()
71         {
72             assert(img.valid, "Invalid dispose call.");
73             WasmImageDispose(img);
74             freeWasmBinary(pixels);
75             img = 0;
76             pixels = null;
77         }
78     }
79 }